<template>
  <slot></slot>
</template>
<script lang="ts" setup>
import { ref, useSlots, onMounted, watch, type Component, type VNode } from 'vue';


// 缓存池（核心）
const cache = new Map<string, { vnode: VNode; component: Component }>()

/**
 * 功能分析：
 * 1.缓存管理	使用 Map 存储组件实例，以 vnode.key 或组件类型作为唯一标识。
 * 2.include/exclude	通过正则或字符串匹配组件名称，决定是否缓存。
 * 3.生命周期钩子	手动触发 activated 和 deactivated 钩子，或通过组合式 API 的 onActivated
 * 4.LRU 算法（简化版）	通过数组 keys 记录顺序，超出 max 时移除最旧缓存（完整版需实现 LRU 队列）。
 */

// 1.创建缓存池
const cacheMap = new Map()
// 2.获取被缓存组件的vnode
const slots = useSlots()

// 动态组件捕获
const activeKey = ref('');

const getDynamicComponent = (): VNode | null => {
  console.log('插槽里的内容', slots)
  const children = slots.default?.()
  console.log('插槽里的内容--', children)
  return children ? children[0] : null
}
// 生成缓存键(核心逻辑)
const generateKey = (vnode: VNode): string => {
  return vnode.type.name || vnode.type.__name || vnode.type.toString()
}

// 3.缓存管理

// 缓存控制逻辑
const cacheComponent = (vnode: VNode) => {

  const key = generateKey(vnode)

  if (!cache.has(key)) {
    cache.set(key, {
      vnode,
      component: vnode.component!
    })
  }
  activeKey.value = key
}

// 激活缓存组件
const activateCached = (key: string) => {
  const cached = cache.get(key)
  if (cached) {
    cached.component.proxy.$parent = getCurrentInstance()?.proxy
    cached.component.isDeactivated = false
    activeKey.value = key
  }
}

// 4. 生命周期钩子处理
// 添加生命周期拦截
const originalUnmount = (vnode: VNode) => {
  const component = vnode.component!
  if (component.isDeactivated) {
    return // 阻止被缓存组件的卸载
  }
  component.um?.() // 调用原始卸载方法
}

// 挂载时缓存
onMounted(() => {
  const vnode = getDynamicComponent()
  console.log('vnode--', vnode)
  if (vnode) cacheComponent(vnode)
})

// 更新时处理
watch(activeKey, (newVal, oldVal) => {
  if (oldVal && oldVal !== newVal) {
    const oldComponent = cache.get(oldVal)?.component
    if (oldComponent) {
      oldComponent.isDeactivated = true
      oldComponent.da?.() // 触发 deactivated 钩子
    }
  }
})

// 5. 渲染控制
// 使用 render 函数控制输出
const render = () => {
  const vnode = getDynamicComponent()
  if (!vnode) return null

  const key = generateKey(vnode)
  const cached = cache.get(key)

  if (cached && cached.component.isDeactivated) {
    // 复用缓存实例
    return cached.vnode
  }

  // 新组件实例
  return vnode
}
</script>